package pluginsintegration

import (
	"github.com/google/wire"
	"go-caipu/pkg/plugins/backendplugin/coreplugin"
	"go-caipu/pkg/plugins/backendplugin/provider"
	"go-caipu/pkg/plugins/manager"
	"go-caipu/pkg/plugins/manager/filestore"
	"go-caipu/pkg/plugins/manager/loader"
	"go-caipu/pkg/plugins/manager/process"
	"go-caipu/pkg/plugins/manager/store"
	"go-caipu/pkg/plugins/repo"
	"go-caipu/pkg/services/pluginsintegration/plugincontext"
	"go-caipu/pkg/tsdb/email"
	"go-caipu/pkg/tsdb/testdata"

	"go-caipu/pkg/plugins"
	"go-caipu/pkg/plugins/manager/client"
	"go-caipu/pkg/plugins/manager/loader/finder"
	"go-caipu/pkg/plugins/manager/registry"
	pluginRegistry "go-caipu/pkg/plugins/manager/registry"
	"go-caipu/pkg/plugins/manager/sources"
	"go-caipu/pkg/setting"
)

// WireSet provides a wire.ProviderSet of plugin
var WireSet = wire.NewSet(
	sources.ProvideService,
	wire.Bind(new(sources.Registry), new(*sources.Service)),

	pluginRegistry.ProvideService,
	wire.Bind(new(pluginRegistry.Service), new(*pluginRegistry.InMemory)),

	finder.NewLocalFinder,
	wire.Bind(new(finder.Finder), new(*finder.Local)),

	//load tsdb
	testdata.ProvideService,
	email.ProvideService,
	
	coreplugin.ProvideCoreRegistry,
	provider.ProvideService,
	wire.Bind(new(plugins.BackendFactoryProvider), new(*provider.Service)),

	loader.ProvideService,
	wire.Bind(new(loader.Service), new(*loader.Loader)),

	process.NewManager,
	wire.Bind(new(process.Service), new(*process.Manager)),
	store.ProvideService,
	wire.Bind(new(plugins.Store), new(*store.Service)),
	ProvideClientDecorator,
	wire.Bind(new(plugins.Client), new(*client.Decorator)),

	plugincontext.ProvidePluginContextProvider,
	repo.ProvideService,
	wire.Bind(new(repo.Service), new(*repo.Manager)),

	manager.ProvideInstaller,
	wire.Bind(new(plugins.Installer), new(*manager.PluginInstaller)),
	//markdown.ProvideService,
	filestore.ProvideService,
	wire.Bind(new(plugins.FileStore), new(*filestore.Service)),
)

// ProvideClientDecorator client
func ProvideClientDecorator(cfg *setting.Cfg, pluginRegistry registry.Service) (*client.Decorator, error) {
	c := client.ProvideService(pluginRegistry, cfg)
	middlewares := CreateMiddlewares(cfg)
	return client.NewDecorator(c, middlewares...)
}

func CreateMiddlewares(cfg *setting.Cfg) []plugins.ClientMiddleware {
	middlewares := []plugins.ClientMiddleware{}
	return middlewares
}
